package whf.framework.util.variable;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;

/**
 * @author WangHaifeng
*/
public class VariableUtils {
	public static String getVariableValue(String input){
		List<Segment> splits = parse(input);
		StringBuffer sb = new StringBuffer(splits.size() * 5);
		for(Segment s: splits) {
			sb.append(s.toString());
		}
		return sb.toString();
	}
	
	private static Object getVariableValue(VariableSegment split) {
		String name = split.getName();
		return name;
	}
	
	public static Object getProperty(Object obj, String property) {
		if(obj == null || StringUtils.isEmpty(property)) return null;
		try{
			return PropertyUtils.getProperty(obj, property);
		}catch(Exception e){
			return null;
		}
	}
	
	private static List<Segment> parse(String input) {
		if(input == null) return null;
		List<Segment> result = new ArrayList<Segment>();
		int startPoint = input.indexOf("${");
		int endPoint = input.indexOf("}", startPoint);
		while(startPoint >= 0 && endPoint > startPoint) {
			String str = input.substring(0, startPoint);
			if(!StringUtils.isEmpty(str)) {
				result.add(new StringSegment(str));
			}
			String name = input.substring(startPoint + 2, endPoint);
			if(!StringUtils.isEmpty(name)) {
				result.add(new VariableSegment(name));
			}
			input = input.substring(endPoint + 1);
			startPoint = input.indexOf("${");
			endPoint = input.indexOf("}", startPoint);
		}
		if(!StringUtils.isEmpty(input)) {
			result.add(new StringSegment(input));
		}
		return result;
	}
	
	static class Segment{
		String name;
		
		public Segment(String name) {
			assert name != null;
			this.name = name;
		}
		
		public String getName() {
			return name;
		}
		
		public String toString() {
			return this.getClass().getName() + ":\n" + name;
		}
		
		public boolean equals(Object o) {
			Segment s = (Segment)o;
			return s.name.equals(name);
		}
		
		public int hashCode() {
			return name.hashCode();
		}
	}
	
	static class StringSegment extends Segment{
		public StringSegment(String name) {
			super(name);
		}
	}
	
	static class VariableSegment extends Segment {
		public VariableSegment(String name) {
			super(name);
		}
		
		public String toString() {
			Object result = getVariableValue(this);
			if(result == null)
				return null;
			else if(result instanceof String)
				return (String)result;
			return result.toString();
		}
	}
}
